package com.gc.widget;

import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Vector;

import android.content.Context;
import android.webkit.WebView;

import com.gc.widget.api.Feature;
import com.gc.widget.api.FeatureFactory;

public class Widget {
	private static final String PATH_ROOT_WIDGET = "/widget/";
	private static final String CONFIG_FILE = "config.xml";
	private static final String LOCALES_FOLDER = "locales";

	private static Widget widget;
	
	public static Widget getWidget() {
		if(widget == null) {
			widget = new Widget();
		}
		return widget;
	}
	

	private Properties props = new Properties(); 
	List<Feature> features = new Vector<Feature>();

	public Widget() {
		InputStream isProps = getClass().getResourceAsStream("/conf.properties");
		if(isProps != null) {
			try {
				props.load(isProps);
			} catch(Exception ex) {
				throw new RuntimeException(ex);
			}
		}
		// TODO 
		
		// plugin = .jar ( .dex et ou .js)
		// service web uri => titre desc, jar
		
		InputStream is = getNonLocalizedWidgetFile(CONFIG_FILE);
		// parse config
		// list features
		// read feature list from config files
		// loop through all features and load classes if exist, fail if required and not exist
		// Map<String,Object> new PluginFactory().load(Map<String,String> params).getJsInterfaces()
		
		// shouldOverrideUrlLoading {
		// String relativePath = getPath(url);
		//  InputStream is = getLocalizedFile(relativePath);
		// if(path.endWith(html,...)
		//    insertJsFiles(os,files);
		// else copyFile(os);
		// }

		// apk generation
		// jars (client + features) to /application.dex
		// copy widget resources => /widget/ xxx
		// create androidmanifest with permissions, intents, activities, services, ...
		// generate androidmanifest.xml, strings, ... => resources.arsc ? 
		// zip to apk, zipalign, sign 

	}
	
	public void loadFeatures(WebView wv, Context ctxt) {
		String[] classesString = props.getProperty("featureFactories","").split(",");
		List<FeatureFactory> factories = new Vector<FeatureFactory>();
		for(String classe : classesString) {
			if(classe.length() == 0)
				continue;
			try {
				FeatureFactory factory = (FeatureFactory)Class.forName(classe).newInstance();
				factories.add(factory);
			} catch(Exception ex) {
				ex.printStackTrace();
			}
		}
		
		for(String featureUri : new String[] {}) {
			Feature feature = null;
			for(FeatureFactory factory : factories) {
				feature = factory.getFeature(featureUri, wv, ctxt, new HashMap<String, String>());
				if(feature != null)
					break;
			}
			//if(feature == null && isRequired(featureUri)) {
				// TODO ! exception ?
			//}
			features.add(feature);
		}
	}

	@SuppressWarnings("unchecked")
	public void dynamicDexLoad(String className, File file) {
		try {
			Class dexFileClass = Class.forName("android.dalvik.DexFile");
			Constructor dexFileClassConstructor = dexFileClass
					.getConstructor(new Class[] { java.io.File.class });

			Object dexFile = dexFileClassConstructor
					.newInstance(new Object[] { file });

			Method dexFileClassLoadClass = dexFileClass.getMethod("loadClass",
					new Class[] { String.class, ClassLoader.class });

			dexFileClassLoadClass.invoke(dexFile,
					new Object[] { className,
							this.getClass().getClassLoader() });
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	public InputStream getWidgetFile(String path) {
		String locale1 = Locale.getDefault().getLanguage() + "-"
				+ Locale.getDefault().getCountry();
		String locale2 = Locale.getDefault().getLanguage();
		String[] searchPaths = { LOCALES_FOLDER + "/" + locale1 + "/",
				LOCALES_FOLDER + "/" + locale2 + "/", "" };
		for (String path2 : searchPaths) {
			InputStream is = getNonLocalizedWidgetFile(path2 + path);
			if (is != null)
				return is;
		}
		return null;
	}

	public InputStream getNonLocalizedWidgetFile(String path) {
		System.out.println("final path " +path);
		return getClass().getResourceAsStream(PATH_ROOT_WIDGET + path);
	}
}
